package com.swgk.core.base.api;

import android.text.TextUtils;

import com.swgk.core.BuildConfig;
import com.swgk.core.base.model.factory.BaseUrlInterceptor;
import com.swgk.core.base.model.factory.CommonInterceptor;
import com.swgk.core.base.model.factory.CryptoConverterFactory;
import com.swgk.core.util.MLog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * app 联网控制器
 */
public class APIManager {
    private static final String TAG = "api";
    public static final String RESPONSE_OK = "ok";
    public static final String REQUEST_SUCCESS = "0";
    public static final String RESPONSE_FAIL = "fail";
    private static APIManager apiManager;

    /**
     * 短响应时间请求 10秒超时
     */
    private OkHttpClient okHttpClient;
    private Retrofit localRetrofit;
    /**
     * 长响应时间请求 150秒超时
     */
    private OkHttpClient uploadHttpClient;
    private Retrofit localRetrofitLong;

    private Builder builder;

    /**
     * 当前借口请求域名
     */
    private int timeOut = 10;

    /**
     * 接口初始化入口
     * 默认不适用网络缓存
     *
     * @return
     */
    public static synchronized APIManager getInstance() {
        if (apiManager == null) {
            apiManager = new APIManager();
        }
        return apiManager.newBuilder().build();
    }

    /**
     * 接口初始化入口
     * 可自定义链式接口使用形式
     *
     * @return Builder
     * @P APIManage
     */
    public static synchronized Builder getBuilder() {
        if (apiManager == null) {
            apiManager = new APIManager();
        }
        if (apiManager.builder == null){
            return apiManager.newBuilder();
        }
        return apiManager.builder;
    }

    public APIManager() {
    }

//    APIManager(Builder builder) {
//        this.timeOut = builder.timeOut;
//        this.okHttpClient = builder.okHttpClient;
//        this.localRetrofit = builder.localRetrofit;
//        this.uploadHttpClient = builder.uploadHttpClient;
//        this.localRetrofitLong = builder.localRetrofitLong;
//        this.builder = builder;
//    }

    /**
     * 接口初始化入口 当切换BaseUrl时调用(只生效一次，下次会还原)
     * 默认不适用网络缓存
     *
     * @return
     */
    public static APIManager getInstance(String changeUrl) {
        if (apiManager == null) {
            apiManager = new APIManager();
        }
        return apiManager.newBuilder().changeUrl(changeUrl).build();
    }

    public static APIManager getInstance(String changeUrl, boolean isCache, boolean isRefresh) {
        if (apiManager == null) {
            apiManager = new APIManager();
        }
        return apiManager.newBuilder().changeUrladdInterceptor(changeUrl, isCache, isRefresh).build();
    }

    /**
     * 接口初始化入口
     *
     * @param isCache   是否从缓存里面取
     * @param isRefresh 是否更新缓存
     * @return
     */
    public static APIManager getInstance(boolean isCache, boolean isRefresh) {
        if (null == apiManager) {
            apiManager = new APIManager();
        }
        return apiManager.newBuilder().addInterceptor(isCache, isRefresh).build();
    }

//    /**
//     * 当切换BaseUrl时调用(永久性生效，下次不会还原)
//     *
//     * @param baseUrl
//     */
//    public static APIManager changeAPIManagerBaseUrl(String baseUrl) {
//        if (null == apiManager) {
//            apiManager = new APIManager();
//        }
//        return apiManager.newBuilder().baseUrl(baseUrl).build();
//    }

    public Builder newBuilder() {
        if (apiManager != null && apiManager.builder != null){
            if (apiManager.builder.interceptorList != null){
                apiManager.builder.interceptorList.clear();
            }
            return apiManager.builder;
        }
        return new Builder(this);
    }

    public APIManager addInterceptor(Interceptor interceptor) {
        if (apiManager != null && apiManager.builder != null){
            if (apiManager.builder.interceptorList != null){
                apiManager.builder.interceptorList.clear();
            }
            return apiManager.builder.addInterceptor(interceptor).build();
        }
        return new Builder(this).addInterceptor(interceptor).build();
    }

    public <T> T create(Class<T> tClass) {
        if (apiManager != null && apiManager.localRetrofit != null){
            return apiManager.localRetrofit.create(tClass);
        }
        return getInstance().newBuilder().build().localRetrofit.create(tClass);
    }

    public <T> T createLong(Class<T> tClass) {
        if (apiManager != null && apiManager.localRetrofitLong != null){
            return apiManager.localRetrofitLong.create(tClass);
        }
        return getInstance().newBuilder().build().localRetrofitLong.create(tClass);
    }

    /**
     * 取消网络请求请求，请求中接口取消会走失败的方法，队列中等待接口直接会取消
     */
    public void cancelOkHttpCalls(boolean isCancelAll) {
        MLog.d("apiLog", "cancelOkHttpCalls");
        if (okHttpClient == null || okHttpClient.dispatcher() == null) return;
        MLog.d("apiLog", String.format("queuedCount=%s,runningCount=%s",
                okHttpClient.dispatcher().queuedCallsCount(),
                okHttpClient.dispatcher().runningCallsCount()));
        //判断是否取消全部请求
        if (isCancelAll) {
            okHttpClient.dispatcher().cancelAll();
            return;
        }
        //取消所有队列中的请求
        for (Call call : okHttpClient.dispatcher().queuedCalls()) {
            call.cancel();
        }
    }

    /**
     * 取消网络请求请求，请求中接口取消会走失败的方法，队列中等待接口直接会取消
     */
    public void cancelOkHttpCallsLong(boolean isCancelAll) {
        MLog.d("apiLog", "cancelOkHttpCallsLong");
        if (uploadHttpClient == null || uploadHttpClient.dispatcher() == null) return;
        MLog.d("apiLog", String.format("queuedCount=%s,runningCount=%s",
                uploadHttpClient.dispatcher().queuedCallsCount(),
                uploadHttpClient.dispatcher().runningCallsCount()));
        //判断是否取消全部请求
        if (isCancelAll) {
            uploadHttpClient.dispatcher().cancelAll();
            return;
        }
        //取消所有队列中的请求
        for (Call call : uploadHttpClient.dispatcher().queuedCalls()) {
            call.cancel();
        }
    }

    /**
     * 联网工具链式构造
     */
    private class Builder {
//        /**
//         * 短响应时间请求 10秒超时
//         */
//        protected OkHttpClient okHttpClient;
//        protected Retrofit localRetrofit;
//        /**
//         * 长响应时间请求 150秒超时
//         */
//        protected OkHttpClient uploadHttpClient;
//        protected Retrofit localRetrofitLong;
        /**
         * 用户自定义拦截器
         */
        List<Interceptor> interceptorList;
        /**
         * 当前借口请求域名
         */
        String changeBaseUrl = "";
        /**
         * 当前借口请求域名
         */
        String baseUrl = BuildConfig.BASE_URL;
        /**
         * 当前借口请求域名
         */
        int timeOut;

        public Builder(APIManager apiManager) {
            this.timeOut = apiManager.timeOut;
        }

        public APIManager build() {
            apiManager.timeOut = timeOut;
            apiManager.okHttpClient = getOkHttpClient(this.timeOut, this.interceptorList);
            apiManager.localRetrofit = getRetrofit(apiManager.okHttpClient);

            apiManager.uploadHttpClient = getOkHttpClient(150, null);
            apiManager.localRetrofitLong = getRetrofit(apiManager.uploadHttpClient);
            apiManager.builder = this;
            return apiManager;
        }

        /**
         * 当切换BaseUrl时调用 永久变更
         *
         * @param baseUrl
         */
        public Builder baseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
            return this;
        }

        /**
         * 当切换BaseUrl时调用 只生效一次
         *
         * @param changeUrl
         */
        public Builder changeUrl(String changeUrl) {
            this.changeBaseUrl = changeUrl;
            return this;
        }

        /**
         * 超时时间
         *
         * @param timeOut
         */
        public Builder timeOut(int timeOut) {
            this.timeOut = timeOut;
            return this;
        }

        public Builder addInterceptor(Interceptor interceptor){
            if (interceptorList == null){
                interceptorList = new ArrayList<>();
            }
            if (interceptor != null){
                interceptorList.add(interceptor);
            }
            return this;
        }

        /**
         * 添加用户级拦截器
         */
        public Builder addInterceptor(boolean isCache, boolean isRefresh) {
            if (interceptorList == null){
                interceptorList = new ArrayList<>();
            }
            Interceptor interceptor = chain -> {
                Request authorised = chain.request().newBuilder()
                        .header("isCache", "" + isCache)
                        .header("isRefresh", "" + isRefresh)
                        .build();
                return chain.proceed(authorised);
            };
            interceptorList.add(interceptor);
            return this;
        }

        /**
         * 临时修改添加更改url和缓存处理
         */
        public Builder changeUrladdInterceptor(String changeUrl, boolean isCache, boolean isRefresh) {
            if (interceptorList == null){
                interceptorList = new ArrayList<>();
            }
            Interceptor interceptor = chain -> {
                Request authorised = chain.request().newBuilder()
                        .header("isCache", "" + isCache)
                        .header("isRefresh", "" + isRefresh)
                        .build();
                this.changeBaseUrl = changeUrl;
                return chain.proceed(authorised);
            };
            interceptorList.add(interceptor);
            this.changeBaseUrl = changeUrl;
            return this;
        }

        /**
         * 初始化  Retrofit
         *
         * @param localOkHttpClient 请求体
         * @return
         */
        private Retrofit getRetrofit(OkHttpClient localOkHttpClient) {
            if (TextUtils.isEmpty(changeBaseUrl)) {
                this.changeBaseUrl = baseUrl;
            }
            return new Retrofit.Builder()
                    .baseUrl(changeBaseUrl)
                    .callFactory(localOkHttpClient)
                    .addConverterFactory(CryptoConverterFactory.create())
                    .build();
        }

        /**
         * 自定义请求体的超时时间和添加拦截器
         *
         * @param timeOut 超时时间
         * @return
         */
        private OkHttpClient getOkHttpClient(int timeOut, List<Interceptor> interceptorList) {
            OkHttpClient.Builder okHttpClientBuilder = initOkHttpClient(timeOut);
            if (interceptorList != null && interceptorList.size() > 0){
                for (Interceptor interceptor:interceptorList){
                    if (interceptor != null) {
                        okHttpClientBuilder.addInterceptor(interceptor);
                    }
                }
            }
            okHttpClientBuilder.addInterceptor(new BaseUrlInterceptor());
            okHttpClientBuilder.addInterceptor(new CommonInterceptor(null));
            return okHttpClientBuilder.build();
        }

        /**
         * 初始化  OkHttpClient
         */
        private OkHttpClient.Builder initOkHttpClient(int timeOut) {
            return new OkHttpClient.Builder()
                    .connectTimeout(timeOut, TimeUnit.SECONDS)
                    .readTimeout(timeOut, TimeUnit.SECONDS)
                    .writeTimeout(timeOut, TimeUnit.SECONDS);
        }
    }
}
